package com.software.exception.exception.handler;

import com.software.exception.exception.enums.ExceptionCode;
import com.software.exception.result.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * @program: springboot-cli-util
 * @author: Wu ZiLin
 * @create: 2023-10-26 17:50
 * @description: controller层接收参数异常处理
 **/
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class RestExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(RestExceptionHandler.class);

    /**
     * 404 - 找不到当前请求
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(NoHandlerFoundException e) {
        logger.error("{}: {}", ExceptionCode.NOT_FOUND.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.NOT_FOUND, "404 Not Found!");
    }

    /**
     * 4005 - 不支持当前请求方法
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public R handleError(HttpRequestMethodNotSupportedException e) {
        logger.error("{}: {}", ExceptionCode.METHOD_NOT_ALLOWED.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.METHOD_NOT_ALLOWED, "请求发生错误!");
    }

    /**
     * 4006 - 缺少请求参数
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(MissingServletRequestParameterException e) {
        logger.error("{}: {}", ExceptionCode.MISSING_REQUEST_PARAM.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.MISSING_REQUEST_PARAM, "请求发生错误!");
    }

    /**
     * 4007 - 请求参数格式错误
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(MethodArgumentTypeMismatchException e) {
        logger.error("{}: {}", ExceptionCode.REQUEST_PARAMETER_FORMAT_INCORRECT.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.REQUEST_PARAMETER_FORMAT_INCORRECT, "请求发生错误!");
    }

    /**
     * 4008 - 参数验证失败
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(MethodArgumentNotValidException e) {
        logger.error("{}: {}", ExceptionCode.PARAMETER_VALIDATION_FAILURE.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.PARAMETER_VALIDATION_FAILURE, "请求发生错误!");
    }

    /**
     * 4009 - 参数绑定失败
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(BindException e) {
        logger.error("{}: {}", ExceptionCode.PARAMETER_BINDING_FAILURE.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.PARAMETER_BINDING_FAILURE, "请求发生错误!");
    }

    /**
     * 4010 - 不支持当前媒体类型
     */
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public R handleError(HttpMediaTypeNotSupportedException e) {
        logger.error("{}: {}", ExceptionCode.MEDIA_TYPE_NOT_SUPPORTED.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.MEDIA_TYPE_NOT_SUPPORTED, "请求发生错误!");
    }

    /**
     * 4011 - 消息不可读
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleError(HttpMessageNotReadableException e) {
        logger.error("{}: {}", ExceptionCode.MESSAGE_UNREADABLE.getMessage(), e.getMessage());
        return R.fail(ExceptionCode.MESSAGE_UNREADABLE, "请求发生错误!");
    }
}

